查看原文
其他

用 Mapbox 做 3D 地图,这篇文章快说透了 (技术&案例大盘点)

Mapbox 2019-06-01

商务合作请联系:apac-bd@mapbox.com

加入开发者交流群请联系微信号:Mapbox_max


我们在上个礼拜为大家整理了 2D 地图创作的神器 Mapbox Studio 入门教程合集《地图界的 PS — Mapbox Studio 入门指南(中英文教程合集)》,没想到获得了很多朋友的阅读、收藏和转发。


🚀 🚀🚀那么既然如此,就一鼓作气把 3D 地图的教程也盘点出来吧。


本文适合于想要入门 3D 地图制作的 Mapboxers,可能搞明白下面任何一个方法,都可以为你的项目带来绝佳的灵感。如果你是大神,请把它转发给你身边的「小白」吧。



💡首先,我们先来看几个具有启发性的案例


3D 地图因为某个用户场景的存在,而有意义。


1. 3D 地图+ 数据可视化:荷兰 3D 通勤线路图


点击这里可以访问在线体验版


这是荷兰 2016 年通勤动态数据可视化图,这是一个使用 Mapbox GL JS 的 custom layer API、基于着色器的实验演示。灵感来自于 cf.city flow 项目,数据来自荷兰统计局


在时空结合之下,有着半透明渐变动效的地图,为通勤数据提供的不仅仅是「可视化」的平台,更是一种艺术和具象的展示,给人以共鸣。


作者很慷慨地贡献了源码,对某些不好理解的部分进行分析,比如如何将自己的 WebGL 内容呈现到底图的同一个 WebGL 上下文中,如果你感兴趣,可以点击这里进入查看源码


2. 3D 地图 + 点云:可视化 LIDAR 点云数据


在城市规划等工作中,难免会需要将倾斜摄影的效果展示在地图上,这样的 3D 地图因其数据量、数据格式等不方便像其他模型那样方便操作。


但其实我们可以使用 Mapbox 与 Uber 合作的可视化工具 deck.gl,结合 Mapbox GL JS,实现这样的效果。



点击这里查看在线网页

支持旋转和缩放,这很酷炫!那么究竟要怎么做呢?别着急,继续往下看,稍后揭晓。


💡那么,用 Mapbox 制作 3D 地图的方式主要有哪些呢?


首先不可否认,你可以做伪 3D 的地图效果,则把具有立体视觉效果的图片载入,在不旋转的情况下,这是一种很不错的、轻量的展示方式,比如开发者故事 | 区块链版大富翁!颜值爆表的 LBS 游戏《无主之城 LORDLESS 》,就曾使用这样的方式。


来源:https://game.lordless.io/guide


但是前面说到的几个例子,又给了我们很多探索的欲望。


其实,崇尚开源开放的 Mapbox 具有很强的延伸力,具体支持什么格式的模型,需要怎么使用等等,很大程度上取决于与 Mapbox 适配的处理库的支持度。


1. 比如用 Three.js 展示 gltf 格式的 3D 模型


在案例 1 中,实现的 3D 效果是借助了 custom layer API,这是 Mapbox GL JS 的一个强大功能,我们从文档就可以看到很不错的效果,下面的模型是 Three.js 所支持的 gltf 格式,我们可以从 Three.js 文档中了解到它所支持的模型种类和相关要求。


来源于 Mapbox GL JS 官方文档案例


在使用源码的时候,其实也不难,在初步了解的时候可以分析源码结构,直接替换相关参数,比如 —— 


我们可以从源码中找到模型的路径,对其进行替换👇



还可以改变模型的位置👇



以及增加光照👇



甚至改变底图的样式👇


我们已经录制好了视频教程,可以戳进来看一下哦。


下面是一位开发者设计的作品,将巴黎圣母院重现在地图上,其实非常简单,就是基于 custom layer 案例的源码改的。


如果您需要修改好的源代码,可以联系 Mapbox 前台小姐姐 Max(微信号:Mapbox_max) ,她会发给您。


2. 使用 extrusions 拉伸获得 3D 建筑效果


如果您没有 3D 模型,想要直接生成 3D 地图,不妨试试这个办法



如果想要好玩一点,可以给建筑们来一段音乐舞蹈,你会发现模型们随着音乐的律动而跳起舞来,您可以到这里查看这个例子的源码



如果你想构建 3D 室内地图,可以参考这个例子



如果想要给建筑贴图,可以参考下面几个视频👇


3. 使用 Deck.gl & Mapbox GL JS,可视化并着色 LIDAR 数据


这一部分相对较长,可以转发,收藏。跳过后续再慢慢看。


点击进入在线体验


现在,使用 Mapbox GL JS 和 Uber Deck.gl,我们可以将这些 LIDAR 点云载入地图的上下文,并为点着色。


如果您在房地产领域,并且需要在地图上以非常高的细节可视化建筑物 - 这可能是展示您投资组合的好方法。比如下面佛罗里达州迈阿密费希尔岛的一个例子。


佛罗里达州费希尔岛,建筑物作为点云层,可以互动,显示房地产价值


以下是使用彩色 LIDAR 点构建自己的 3D 地图的方法,一起来可视化金门大桥吧。


首先,请访问 NOAA Elevation 网站的资源,搜索 Elevation,选择 2016 USGS LIDAR West Coast El Nino (WA, OR, CA)。



接下来我们搜索 Imagery ,选择 2016 Coastal California NAIP 4-band 8 bit Imagery。



接下来,更改“Provision your data”中的一些设置。由于 Mapbox 使用 web mercator,而 Deck.gl 使用度量值作为高度,因此这些设置可以缩减后续步骤(例如重新投影 LIDAR 和 Imagery 文件)。



完成此操作后,请提交。您将收到来自 NOAA 的两封电子邮件,其中包含 LIDAR 和图像文件的下载链接。


下面就很好玩啦!我们可以将数据导入 QGIS!请注意,在解压缩两个下载后,我们将 LIDAR 的文件扩展名更改为“csv” ,默认情况下为“txt”。


使用“Delimited Text File”图标创建图层,将 LIDAR 数据添加到 QGIS


如果你下载了相同的数据,你将获得很多积分,差不多有500万!


下面的目标是,将此数字过滤为仅呈现您需要的功能。通过创建一个多边形图层,并使用剪辑工具在下面的示例中使用“Mask 蒙版”,并且过滤掉小于零的高程。如果编辑好了,可以将文件另存为 ESRI shapefile。


使用 shapefile “mask”剪切 LIDAR 数据


编辑 LIDAR 数据后,是时候将图像文件加载到 QGIS 中了。



第一项工作是将 Geotiff 保存为渲染图像。



现在我们将在 QGIS 的处理菜单中使用一个工具:'gdal2xyz':



我们批量运行此工具:我们希望制作3  个 CSV 文件,每个通道一个,以获得每个纬度和经度的红色,绿色和蓝色值。


加载您生成的三个 CSV:



为了更轻松,我们可以更改文件中的字段名称:在 LIDAR 中,将经度重命名为 X,将纬度重命名为 Y,将高程重命名为 Z;在红色,绿色和蓝色 CSV 中,将它们保存为 ESRI Shapefile,并将 Field_3 分别更改为红色,绿色和蓝色。


为 QGIS 使用'NNJoin'插件,为 LIDAR 中的每个点添加最接近的颜色值,因此必须进行三次连接。目标是最终得到以下属性:X | Y | Z |红色|绿色|蓝色。


使用'NNJoin'插件获取每个 LIDAR 点的颜色值


下面,让我们将 shapefile 保存为 CSV,以便我们可以开始构建 Deck.gl 将解析的数组。



您可以使用很多方法和工具来构建阵列,这里根据习惯使用 Tableau,您甚至可以使用字段计算器在 QGIS 中构建阵列。但是,基本原理是一样的,我们需要一个串联的字符串。就像是:


"["+STR([X])+","+STR([Y])+","+STR([Z])+","+STR([Red])+","+STR([Green])+","+STR([Blue])+"],"


现在你已经构建了数组,在记事本中用“[”和“],”前缀和后缀数组,并将其保存为'array.json'。将它保存到CORS兼容的网站并分享,类似 Dropbox 应该工作。


下面是一个代码模板来帮助您入门!


<html>
<head>
<title>Deckgl RGB PointCloud + Mapbox</title>
<script src="https://unpkg.com/deck.gl@^7.0.0/dist.min.js"></script>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.54.0/mapbox-gl.js"></script>
<link rel="stylesheet" type="text/css" href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.54.0/mapbox-gl.css">
<style>
body {
background-color: #000000;
margin: 0;
}
#map {
height: 100vh;
width: 100%;
margin: 0 auto;
}
</style>
</head>

<body>
<div id="map"></div>
</body>
<script type="text/javascript">
const { MapboxLayer, PointCloudLayer } = deck;
//REPLACE WITH YOUR MAPBOX ACCESS TOKEN
mapboxgl.accessToken = 'your token here';
const map = new mapboxgl.Map({
container: 'map',
//REPLACE THIS WITH THE MAPBOX STYLE URL OF YOUR CHOICE
style: 'mapbox://styles/allanwalker/cjpn18pta036u2roe5ootbwwp?fresh=true',
center: [-122.476622, 37.817516],
zoom: 15.40,
bearing: -34.40,
pitch: 60
});
map.on('style.load', () => {
map.addLayer(new MapboxLayer({
id: 'deckgl-PointCloudLayer',
type: PointCloudLayer,
//REPLACE THIS WITH THE URL OF THE FILE
data: 'array.json',
getPosition: d => [d[0], d[1], d[2]],
getColor: d => [d[3], d[4], d[5]],
sizeUnits: 'meters',
pointSize: 0.75,
opacity: 1
}));
});
</script>
</html>


最终可视化金门大桥的效果如下:



4. 使用 Maps SDK for Unity 发挥最大程度的 3D 地图能力


如果是 3D 导航地图、3D LBS 游戏等重 3D 的应用,比较推荐您看看 Maps SDK for Unity


下面是几个官方附带的例子,当您配置好软件环境以后就可以直接加载并编辑这些 3D 地图案例。


模拟城市


在 3D 建筑层中的数据可视化探索


标志性建筑展示


太空人游戏


桌面 AR 建筑展示

还有更多的案例,可以在这里了解更多。您会发现,Unity 的 3D 地图功能是非常强大的,基本上可以实现您心目中的大部分创意。


有一位开发者团队,一个程序,一个美术,使用 Maps SDK for Unity 开发了一款面向LBS运动爱好者的核心向作品《结界都市Return》,目前正在 Taptap 平台上开放预约

<<  滑动查看下一张图片  >>


💡最后,放一些开发者们用 Mapbox 制作的 3D 案例吧!


首先,在不久前落幕的 3D 地图设计大赛中,我们收到了很多优秀的作品,其中有两个非常棒。


@leisure 《富有质感的 3D 城市版图》


作者使用细腻的「笔触」描绘了城市的 3D 版图,高级感满满,看来一定是用了很大的功夫去调整的。


点击这里进入在线版


这位开发者已经在 Mapbox 开发者社群分享过相关的内容,如果你想认识他,可以联系 Max(微信号 Mapbox_max ) 拉你入群。

@七彩皮皮修 《权利的游戏 3D 故事导览》


作者的灵感来源是 Mapbox Studio 中权力的游戏地图模版结合 custom layer API,结合权利的游戏故事理解,做了一个非常精美的 3D 故事在线导览。


点击这里进入在线版


如果想要了解更多,可以进入作者的掘金主页查看细节👇

https://juejin.im/post/5ccab910f265da035378ec43

恭喜你,终于看完了这篇长长的技术&教程指南,如果喜欢的话,请点一下「在看」并转发给相关的朋友吧!


我们将会不定期放出相关的内容,可以关注 Mapbox 微信公众号并小小期待一下 ❤️




👀相关阅读


👀点击关键词查看相关内容


商务合作请联系:apac-bd@mapbox.com

扫描下方二维码,回复【技术】即可加入开发者群,对接资源,一起学习成长。👇

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存